//
//  QDMetroTicketViewController.swift
//  QDMetroClient
//
//  Created by YueWen on 2019/2/27.
//  Copyright © 2019 YueWen. All rights reserved.
//

import UIKit
import HandyJSON

typealias QDMetroStationFooterView = QDPayTypeFooterView

/// 购买车票的控制器
final class QDMetroTicketViewController: NWTableViewController {

    enum QDMetroTicketControllerType {
        /// 默认买票流程
        case `default`
        /// 从车票界面进来
        case fromTicket
    }

    /// 线网图
    lazy private var rightItem: UIBarButtonItem = {
       
        let button = UIButton()
        button.setTitle("线网图", for: .normal)
        button.adjustsImageWhenHighlighted = false
        button.setTitleColor(QDColors.separator, for: .normal)
        button.titleLabel?.font = Font.regular.font(size: 14)
        button.addTarget(self, action: #selector(gotoMetroLineWebView), for: .touchUpInside)
        /// 小于11
        if (UIDevice.current.systemVersion as NSString).floatValue < 11.0 {
            button.ritl_size = CGSize(width: 42, height: 32)
        }
        
        return UIBarButtonItem(customView: button)
    }()
    
    /// 地铁站点的视图
    private let stationHeaderView = QDMetroStationHeaderView()
    /// 底部的温馨提示
    private let stationFooterView = QDMetroStationFooterView()
    
    /// 底部放置价格的bottom
    private let priceBottomView = UIView()
    /// 购买按钮
    private let buyButton = UIButton()
    /// 底层的横线
    private let topLine = CALayer()
    /// 显示价格的标签
    private let priceLabel = UILabel()
    /// 支付类型选择视图
    lazy private var payTypeView: QDPayTypePickerView = {
        
        let pickerView = QDPayTypePickerView()
        pickerView.typeDelegate = self
        return pickerView
    }()
    
    /// 浮动窗口
    private let floatImageView = UIImageView()
    /// 显示购买记录
    private let floatLabel = UILabel()
    
    
    
    //MARK: Data
    /// 开始站点
    var startStation = QDMetroSimpleStation()
    /// 终点站点
    var endStation = QDMetroSimpleStation()
    /// 买票模式
    var type: QDMetroTicketViewController.QDMetroTicketControllerType = .`default`
    /// fromTicket 模式下的回调方法
    var resultHandler: ((String) ->())?
    /// 当前张数
    private var count = 1
    /// 最大票数
    private var maxCount = -1
    /// 单价
    private var price = 0.0
    /// 更新显示的单价
    private var updatePrice: String {
        return String(format: "%.2f", Float(price))
    }
    /// 总价
    private var totalPrice = 0.0
    /// 更新显示的总价
    private var updateTotalPrice: String {
        return String(format: "%.2f", price * Double(count))
    }

    /// 站点类型,表示是进站点击还是出站点击
    private var headerType:QDMetroStationHeaderView.StationType = .start
   
    
    convenience init(start: QDMetroSimpleStation = QDMetroSimpleStation(),
                     end: QDMetroSimpleStation = QDMetroSimpleStation()) {
        self.init()
        startStation = start
        endStation = end
    }
    

    /// 站点选择控制器
    lazy private var selectStationController: QDStationsViewController = {
        return QDStationsViewController(type: .select, delegate: self)
    }()
    
    override func loadPropertysAtInitialization() {
        super.loadPropertysAtInitialization()
        
        headerRefreshEnable = false
        footerRefreshEnable = false
        hidesBottomBarWhenPushed = true
    }
    
    override func registerTableViewCellsAndReusableView() {
        tableView.register(QDMetroCountTableViewCell.self, forCellReuseIdentifier: "cell")
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        // Do any additional setup after loading the view.
        navigationItem.title = "车票购买"
        navigationItem.rightBarButtonItem = rightItem
        
        priceBottomView.backgroundColor = .white
        
        buyButton.adjustsImageWhenHighlighted = false
        buyButton.setTitle("购买", for: .normal)
        buyButton.setTitleColor(.white, for: .normal)
        buyButton.backgroundColor = QDColors.theme
        buyButton.titleLabel?.font = Font.regular.font(size: 18)
        buyButton.addTarget(self, action: #selector(purchaseDidTap), for: .touchUpInside)
        
        topLine.backgroundColor = 230.ritl_color.cgColor
        
        priceLabel.backgroundColor = .white
        priceLabel.textAlignment = .center
        priceLabel.text = "单价 0 元 总价 0 元"
        
        
        view.addSubview(priceBottomView)
        priceBottomView.addSubview(buyButton)
        priceBottomView.layer.addSublayer(topLine)
        priceBottomView.addSubview(priceLabel)
        
        topLine.position = .zero
        topLine.anchorPoint = .zero
        topLine.bounds = CGRect(origin: .zero, size: CGSize(width: ritl_width - 120, height: 0.5))
        
        floatImageView.image = "float_background".namedImage
        floatImageView.ritl_size = CGSize(width: 70, height: 70)
        floatImageView.isUserInteractionEnabled = true
        
        floatLabel.text = "车票订单"
        floatLabel.textColor = .white
        floatLabel.font = Font.regular.font(size: 14)
        floatLabel.numberOfLines = 2
        
        floatImageView.addUIControlHandler { [unowned self](_) in
            print("进入列表")
            self.ritl_topNavigationPush(QDTicketPageViewController(), animated: true)
        }
        
        //追加拖动手势
        let panRecongnizer = UIPanGestureRecognizer(target: self, action: #selector(handlePan(recongnizer:)))
        floatImageView.addGestureRecognizer(panRecongnizer)
        
        view.addSubview(floatImageView)
        floatImageView.addSubview(floatLabel)
        
        floatImageView.snp.makeConstraints { (make) in
            make.right.equalToSuperview().inset(9)
            make.height.width.equalTo(70)
            make.bottom.equalToSuperview().inset(BarDistance.TabBar.height)
        }
        
        floatLabel.snp.makeConstraints { (make) in
            make.top.equalToSuperview().offset(12)
            make.height.equalTo(40)
            make.width.equalTo(28)
            make.centerX.equalToSuperview()
        }

        priceBottomView.snp.makeConstraints { (make) in
            make.left.right.bottom.equalToSuperview()
            make.height.equalTo(BarDistance.TabBar.height)
        }
        
        buyButton.snp.makeConstraints { (make) in
            make.right.top.equalToSuperview()
            make.height.equalTo(BarDistance.TabBar.normalHeight)
            make.width.equalTo(ritl_width == 320 ? 90 : 120)
        }
        
        priceLabel.snp.makeConstraints { (make) in
            make.left.equalToSuperview().offset(0)
            make.top.equalToSuperview().offset(0.5)
            make.right.equalTo(buyButton.snp.left)
            make.height.equalTo(BarDistance.TabBar.normalHeight - 0.5)
        }
        
        // header
        stationHeaderView.frame = CGRect(origin: .zero, size: CGSize(width: ritl_width, height: CGFloat(QDMetroStationHeaderHeight)))
        stationHeaderView.delegate = self
        tableView.tableHeaderView = stationHeaderView
        
        // footer
        stationFooterView.subtitleLabel1.text = "1.请至购票起始站扫码取票，取票站当日进站有效。"
        stationFooterView.subtitleLabel2.text = "2.扫码取票仅一次使用有效，逾期未取票自动退款。"
        stationFooterView.frame = CGRect(origin: .zero, size: CGSize(width: ritl_width, height: stationFooterView.height))
        tableView.tableFooterView = stationFooterView
        
        updateStationHeaderView()
        updatePriceMessage(price: "0.00", total: "0.00")
        requestMaxCount()
    }
    
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        view.endEditing(true)
    }
    
    
    override func makeTableViewConstraints() {
        
        tableView.snp.makeConstraints { (make) in
            make.left.right.top.equalToSuperview()
            make.bottom.equalToSuperview().inset(BarDistance.TabBar.height)
        }
    }
    
    
    /// 处理拖动手势
    @objc func handlePan(recongnizer: UIPanGestureRecognizer) {
        
        /// 执行动画
        func removeFloatImageViewAnimated(){
         
            //获得中点
            let centerX = floatImageView.center.x
            let centerY = floatImageView.center.y
            
            var toPointX = 0
            var toPointY = centerY
            let duration = CGFloat(0.8)
            var distance = CGFloat(0.0) //距离
            let maxDistance = ritl_width / 2.0 - 70 / 2
            
            if centerX < ritl_width / 2.0 {//位于左半屏
                toPointX = Int(0.5 * 70) + 9
            }else {
                toPointX = Int(ritl_width - 70 * 0.5) - 9
            }
            
            let minCenterY = 70 * 0.5 + 10 + BarDistance.NavigationBar.height//上边距10
            let maxCenterY = ritl_height - 70 * 0.5 - BarDistance.TabBar.height
            
            if centerY < CGFloat(minCenterY) {//太过往上
                toPointY = CGFloat(minCenterY)
            }else if centerY > CGFloat(maxCenterY) {
                toPointY = maxCenterY
            }
            
            distance = abs(CGFloat(toPointX) - centerX)
            let timeScale = CGFloat(distance) / maxDistance
            
            // 执行动画
            UIView.animate(withDuration: TimeInterval(duration * timeScale), delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.3, options: .curveLinear, animations: {
                
                self.floatImageView.ritl_centerX = CGFloat(toPointX)
                self.floatImageView.ritl_centerY = toPointY
                
            }, completion: nil)
        }
        
        let point = recongnizer.location(in: recongnizer.view)//获得point
        let converPoint = recongnizer.view?.convert(point, to: view)//进行坐标转换
        floatImageView.center = converPoint ?? .zero
        
        switch recongnizer.state {
        case .ended: fallthrough
        case .cancelled: fallthrough
        case .failed: removeFloatImageViewAnimated()
            
        default: break
        }
    }
}





extension QDMetroTicketViewController: QDPayTypePickerViewDelegate {
    
    func payTypePickerView(view: QDPayTypePickerView, select type: QDPayType) {
        
        view.dismissAnimated()
        //TODO: 请求订单并请求支付信息
        requestTicketOrder(type: type)
    }
}




extension QDMetroTicketViewController: QDMetroStationHeaderViewDelegate {

    /// 选择站点
    func metroStationHeaderView(view: QDMetroStationHeaderView, didActionType: QDMetroStationHeaderView.StationType) {
        
        headerType = didActionType
        ritl_topNavigationPush(selectStationController, animated: true)
    }
    
    /// 交换起始站
    func overStartAndEndStaion(view: QDMetroStationHeaderView) {

        (startStation,endStation) = (endStation,startStation)
        updateStationHeaderView()
    }
}




extension QDMetroTicketViewController : QDStationsViewSelectAction {
    
    /// 选择了
    func stationsViewController(didSelect stationName: String, stationId: String, line: [String]) {
        
        guard stationId != startStation.id && stationId != endStation.id else {
            view.showTextHUD(text: "不能选择相同站点");  return
        }
        
        //进行填充
        if headerType == .start {
            startStation.setId(id: stationId)
            startStation.setName(name: stationName)
        }else {
            endStation.setId(id: stationId)
            endStation.setName(name: stationName)
        }
        
        updateStationHeaderView()
        
        //如果站点发生了变化并且符合规则,进行单价查询
        if hasStation().0 { requestPrice() }
    }
}



extension QDMetroTicketViewController {
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return maxCount < 0 ? 0 : 1
    }
    
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        
        if let countCell = cell as? QDMetroCountTableViewCell{
            countCell.countActor = self
            countCell.count = maxCount
        }
        return cell
    }
    
    
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return QDMetroCountTableViewCell.height(count: maxCount)
    }
}




extension QDMetroTicketViewController: QDMetroCountChangeActor {
    
    func metroCountTableViewCell(cell: QDMetroCountTableViewCell, currentIndex: NSInteger) {
        count = currentIndex + 1
        
        //如果存在起始站，计算价格
        if hasStation().0 && price > 0.0 {
            updatePriceMessage(price: updatePrice, total: updateTotalPrice) //手动计算价格
        }else if hasStation().0 {//进行请求价格
            requestPrice()
        }
    }
}



extension QDMetroTicketViewController {
    
    /// 更新价格信息，单价以及总计
    private func updatePriceMessage(price: String, total: String){
        
        //转成属性字符串
        let descString = "单价 \(price) 元 总价 \(total) 元"
        let style = NSMutableParagraphStyle()
        style.alignment = .center
        
        let attributeString = NSMutableAttributedString(string: descString, attributes: [.font: Font.regular.font(size: 15),
                                                                                         .foregroundColor: QDColors.black,
                                                                                         .paragraphStyle: style])
        
        let desc = descString as NSString
        let priceRange = desc.range(of: price)
        let totalRange = desc.range(of: total, options: .backwards)
        
        attributeString.addAttributes([.font : Font.regular.font(size: 20),
                                       .foregroundColor: QDColors.orange], range: priceRange)
        
        attributeString.addAttributes([.font : Font.regular.font(size: 20),
                                       .foregroundColor: QDColors.orange], range: totalRange)
        
        priceLabel.attributedText = attributeString
    }
    
    
    /// 更新起始站点的内容
    private func updateStationHeaderView(){

        stationHeaderView.startTitle = startStation.name
        stationHeaderView.endTitle = endStation.name
    }
    
    
    /// 检查是否可以购买
    private func shouldPurpurchase() -> (Bool,String){
        
        let (result,msg) = hasStation()
        if !result { return (result,msg) }
        
        if price == 0.0 {
            return (false, "暂时无法购票")
        }
        
        return (true,"检查成功")
    }
    
    
    /// 是否存在站点信息
    private func hasStation() -> (Bool,String) {
        
        guard !startStation.id.isEmpty else {
            return (false,"请选择起点")
        }
        
        guard !endStation.id.isEmpty else {
            return (false, "请选择终点")
        }
        
        return (true,"检查成功")
    }
}



extension QDMetroTicketViewController: QDLineGraphViewControllerPurchaseDelegate {
    
    /// 点击进入线网图
    @objc func gotoMetroLineWebView(){
        ritl_topNavigationPush(QDLineGraphViewController(delegate: self), animated: true)
    }
    
    /// 购买
    @objc func purchaseDidTap(){
        
        //TODO:检查数据
        let (result,msg) = shouldPurpurchase()
        if !result {
            view.showTextHUD(text: msg); return
        }
        
        //弹出支付
        payTypeView.show()
    }
    
    
    func lineGraphViewController(viewController: QDLineGraphViewController, start: (stationId: String, stationName: String), end: (stationId: String, stationName: String)) {
        
        //进行填充
        startStation = QDMetroSimpleStation(id: start.stationId, name: start.stationName)
        endStation = QDMetroSimpleStation(id: end.stationId, name: end.stationName)
        
        //更新UI
        updateStationHeaderView()
        //进行价格计算
        requestPrice()
    }
    
}


extension QDMetroTicketViewController {
    
    /// 计算最大数量
    private func requestMaxCount(){
        
        QDNetworkingManager.request(url: getMaxCountUrl, success: { (msg, data) in
            
            guard let maxCount = data["maxCount"] as? String else { return }
            // 进行赋值
            self.maxCount = Int(maxCount) ?? 0
            // 进行张数默认,最少为1张
            self.count = max(1, min(self.count, self.maxCount))
            // 刷新界面
            self.tableView.reloadData()
            
            //如果存在数据
            if self.hasStation().0 {
                self.requestPrice()//请求价格
            }
            
        }) { (msg, errorType) in
            
            self.view.showTextHUD(text: msg)
            self.buyButton.isEnabled = false//变为不可用
        }
    }
    
    
    /// 计算价格
    private func requestPrice(){
        
        view.showWatingHUD()
        QDNetworkingManager.request(url: getPriceUrl, paramteres: ["entryStation":startStation.id,"exitStation":endStation.id], success: { (msg, data) in
 
            self.view.dismissHUD()
            
            guard let price = data["price"] as? String else { return }
            
            // 更新数据源
            self.price = (Double(price) ?? 0.0) / 100.0
            self.totalPrice = self.price * Double(self.count)
            self.updatePriceMessage(price: self.updatePrice, total: self.updateTotalPrice)//更新
            
        }) { (msg, errorType) in
            
            // 重置数据源
            self.price = 0.0
            self.totalPrice = self.price * Double(self.count)
            self.updatePriceMessage(price: self.updatePrice, total: self.updateTotalPrice)//更新
            self.view.dismissHUD()
            self.view.showTextHUD(text: msg)
        }
    }
    

    
    /// 请求在线购票的订单
    private func requestTicketOrder(type: QDPayType) {
        
        self.view.showTextHUD(text: "正在请求支付信息", delayHidden: 20)
        
        /// 解析体
        struct QDRequestTicketResutContainer: HandyJSON {
            /// 订单号
            var orderNo = ""
            /// 唤起支付的信息
            var paymentInfo = ""
        }

        QDNetworkingManager.request(url: onlineTicketUrl, paramteres: ["entryStation" : startStation.id,"exitStation" : endStation.id,"count" : count, "totalAmount" : "\(price * Double(100 * count))","channel" : type.rawValue], success: { (msg, data) in

            //获得paymentInfo
            guard let requestContainer = QDRequestTicketResutContainer.deserialize(from: data) else {
                self.view.showTextHUD(text: "数据解析错误."); return
            }
            
            self.view.showTextHUD(text: "正在唤起支付渠道", delayHidden: 10)
            
            //开始支付
            QDPaymentManager.sharedInstance.pay(type: type, data: requestContainer.paymentInfo, orderId: requestContainer.orderNo, delegate: self, viewController: self)
            

        }) { (msg, errorType) in
            self.view.showTextHUD(text: msg)
        }
    }
}


extension QDMetroTicketViewController: QDPaymentManagerDelegate {
    
    /// 支付成功
    func complete(orderId: String) {
        //支付成功，跳转
        view.showTextHUD(text: "支付成功!")
        
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
            
            if self.type == .`default` {
                self.pushTicketDetailController(orderId: orderId); return
            }
            
            //进行回调
            self.resultHandler?(orderId)
            self.navigationController?.popViewController(animated: true)
        }
    }
    
    /// 支付失败
    func fail(error: String, orderId: String) {
        //支付成功，跳转
        view.showTextHUD(text: "支付失败!")
        
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 1) {
            
            if self.type == .`default` {
                self.pushTicketDetailController(orderId: orderId); return
            }
            
            //进行回调
            self.resultHandler?(orderId)
            self.navigationController?.popViewController(animated: true)
        }
    }
    
    
    /// 弹出车票详情
    func pushTicketDetailController(orderId: String){
        ritl_topNavigationPush(QDTicketDetailViewController(orderNum: orderId), animated: true)
    }
}
